/**
 * 
 */
package tree.passed2;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
 * @author michael
 *
 */
public class TreeTraversalLC {

	//Definition for binary tree
	public class TreeNode {
		int val;
	    TreeNode left;
	    TreeNode right;
	    TreeNode(int x) { val = x; }
	}
    /*
	Given a binary tree, return the preorder traversal of its nodes' values.

			For example:
			Given binary tree {1,#,2,3},
			   1
			    \
			     2
			    /
			   3
			return [1,2,3].
	*/
    public List<Integer> preorderTraversal(TreeNode root) {
        final List<Integer> result = new LinkedList<>();
        if (root == null) return result;
            
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        
        return result;
    }
	
    /*
    Given a binary tree, return the inorder traversal of its nodes' values.

    		For example:
    		Given binary tree {1,#,2,3},
    		   1
    		    \
    		     2
    		    /
    		   3
    		return [1,3,2].
    */
    public List<Integer> inorderTraversal(TreeNode root) {
    	final List<Integer> result = new LinkedList<>();
    	if (root == null) return result;
    	
    	Stack<TreeNode> stack = new Stack<>();
    	TreeNode currNode = root;
    	while (!stack.isEmpty() || currNode != null) {
    		if (currNode != null) {
    			stack.push(currNode);
    			currNode = currNode.left;
    		}
    		else {
    			TreeNode node = stack.pop();
    			result.add(node.val);
    			currNode = node.right;
    		}
    	}
    	
    	return result;
    }
    
    /*
	 Given a binary tree, return the postorder traversal of its nodes' values.
	
	For example:
	Given binary tree {1,#,2,3},
	   1
	    \
	     2
	    /
	   3
	return [3,2,1].
     */
    public List<Integer> postorderTraversal(TreeNode root) {
        final List<Integer> result = new LinkedList<>();
        if (root == null) return result;
        
        Stack<TreeNode> stack = new Stack<>();
        TreeNode currNode = root;
        while (!stack.isEmpty() || currNode != null) {
        	if (currNode != null) {
        		stack.push(currNode);
        		currNode = currNode.left;
        	}
        	else {
        		while (!stack.isEmpty() && currNode == stack.peek().right) {
        			currNode = stack.pop();
        			result.add(currNode.val);
        		}
        		currNode = stack.isEmpty() ? null : stack.peek().right;
        	}
        }
        
        return result;
    }
    
	/**
	 * 
	 */
	public TreeTraversalLC() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}



//ArrayList<Integer> ret = new ArrayList<Integer>();
//Stack<TreeNode> stack = new Stack<TreeNode>();
//TreeNode current = root;
//while (!stack.isEmpty() || current != null) {
//    if (current != null) {
//        stack.push(current);
//        current = current.left;
//    }
//    else {
//        while (!stack.isEmpty() && current == stack.peek().right) {
//            current = stack.pop();
//            ret.add(current.val);    
//        }
//        
//        current = stack.isEmpty() ? null : stack.peek().right;
//    }
//}
//return ret;
